<template>
  <div class="main_content">
    <father-title></father-title>
    <div class="contentBox">
      <div class="left">
        <div class="dept_content">
          <div v-if="$store.state.perms.includes('sys:menu:save')" class="header" @click="addRoot">新增根节点</div>
          <div :class="['tree', $store.state.perms.includes('sys:menu:save')?'':'tree-radius']">
            <Tree :data="menuList" :render="renderTreeContent"></Tree>
          </div>
        </div>
      </div>
      <div class="right" v-show="title">
        <div class="header">
          <div class="line"></div>
          <div class="title">{{title}}</div>
        </div>
        <Form
            ref="form"
            :model="formValidate"
            :rules="ruleValidate"
            label-position="top"
            slot="content">
          <FormItem label="菜单类型" prop="type">
            <RadioGroup v-model="formValidate.type">
              <Radio :label="item.value" v-for="item in menuType" :key="item.value">{{item.key}}</Radio>
            </RadioGroup>
          </FormItem>
          <FormItem label="菜单名称" prop="name">
            <Input v-model="formValidate.name" placeholder="请输入菜单或按钮名称" />
          </FormItem>
          <FormItem v-if="formValidate.type === 1" label="菜单URL" prop="url" :rules='[{required: true, message: "菜单URL不能为空", trigger: "blur"}]'>
            <Input v-model="formValidate.url" placeholder="请输入菜单URL" />
          </FormItem>
          <FormItem v-if="formValidate.type !== 0" label="授权标识" prop="perms" :rules='[{required: false, message: "授权不能为空", trigger: "blur"}]'>
            <Input v-model="formValidate.perms" placeholder="请输入授权标识" />
          </FormItem>
          <FormItem v-if="formValidate.type === 1" label="打开方式" prop="open" :rules='[{required: true, type: "number", message: "请选择打开方式", trigger: "change"}]'>
            <RadioGroup v-model="formValidate.open">
              <Radio :label="item.value" v-for="item in openType" :key="item.value">{{item.key}}</Radio>
            </RadioGroup>
          </FormItem>
          <FormItem v-if="formValidate.type === 1" label="是否隐藏" prop="hidden" :rules='[{required: true, type: "number", message: "请选择", trigger: "change"}]'>
            <RadioGroup v-model="formValidate.hidden">
              <Radio :label="item.value" v-for="item in hiddenType" :key="item.value">{{item.key}}</Radio>
            </RadioGroup>
          </FormItem>
          <FormItem v-if="formValidate.type !== 2" label="序号" prop="orderNum" :rules='[{required: true, type: "number", message: "序号不能为空，且必须为数字", trigger: "blur"}]'>
            <Input type="text" number v-model="formValidate.orderNum" placeholder="请输入序号用于排序" />
          </FormItem>
          <FormItem v-if="formValidate.type !== 2" label="菜单图标" prop="icon" :rules='[{required: true, message: "请选择菜单图标", trigger: "blur"}]'>
            <Input v-model="formValidate.icon" placeholder="请选择菜单图标" @click.native="iconSelectorVisible = true" readonly />
          </FormItem>
        </Form>
        <Button v-if="$store.state.perms.includes('sys:menu:update')" :loading="loading" style="width: 80px;margin-top: 10px" type="primary" @click="addOrEditData">提交</Button>
      </div>
    </div>

    <IconSelector :visible.sync="iconSelectorVisible" @ok="iconChange" />
  </div>
</template>

<script>
import {formValidate, ruleValidate, menuType, openType, hiddenType} from "./pageConfig";

export default {
  name: 'MenuManage',

  data() {
    return {
      menuType,
      openType,
      hiddenType,
      formValidate: {...formValidate},
      ruleValidate,
      menuList: [],
      activeNode: null,
      loading: false,
      title: null,
      iconSelectorVisible: false,
    };
  },

  mounted() {
    this.getList();
  },

  computed: {},

  methods: {
    // 修改图标
    iconChange(icon) {
      this.formValidate.icon = icon;
    },
    // 添加根节点
    addRoot(){
      this.activeNode = {menuId: 0, name: "一级菜单"};
      this.formValidate = {...formValidate};
      this.title = "新增根节点";
    },

    // 删除数据
    deleteData(e, data){
      this.$Modal.confirm({
        title: '删除',
        content: `是否删除${data.name}？`,
        loading: true,
        onOk: () => {
          this.$api.post('sp/sys/menu/delete', {menuId: data.menuId}).then((res)=>{
            if(res.data.code === 0){
              this.getList();
              this.$Message.success('删除成功');
            }
          }).finally(()=>this.$Modal.remove());
        }
      });
      // 阻止冒泡
      e.stopPropagation();
    },

    // 新增数据
    addData(e, data){
      this.activeNode = data;
      this.formValidate = {...formValidate};
      this.title = "新增";
      // 阻止冒泡
      e.stopPropagation();
    },

    // 修改数据
    editData(e, data){
      this.activeNode = data;
      let form = {...formValidate};
      Object.keys(form).forEach((key) => form[key] = data[key]);
      this.formValidate = form;
      this.title = "编辑 - " + data.name;
      // 阻止冒泡
      e.stopPropagation();
    },

    // 新增或修改
    addOrEditData(){
      // 校验数据
      this.$refs.form.validate(state => {
        if (!state){
          return this.$Message.warning("请填写对应的值");
        }
        this.loading = true;
        // 判断新增或修改
        if(this.formValidate.menuId){
          this.$api.post('sp/sys/menu/update', this.formValidate).then((res)=>{
            if(res.data.code === 0){
              this.getList();
              this.$Message.success("修改成功");
            }
          }).finally(()=> this.loading = false);
        }else{
          this.formValidate.parentId = this.activeNode.menuId;
          this.formValidate.parentName = this.activeNode.name;
          this.$api.post('sp/sys/menu/save', this.formValidate).then((res)=>{
            if(res.data.code === 0){
              this.activeNode = null;
              this.title = null;
              this.getList();
              this.$Message.success("新增成功");
            }
          }).finally(()=> this.loading = false);
        }

      });
    },

    // 获取列表
    getList(){
      this.$api.get("sp/sys/menu/list").then((res)=>{
        if(res.data.code === 0){
          // 重新组装数据
          this.menuList = res.data.data.map(p => {
            let item = this.parseChildren(p);
            item.expand = true;
            return item;
          });
        }
      });
    },
    // 解析数据
    parseChildren(node) {
      return {
        ...node,
        expand: true,
        title: node.name,
        children: node.children !== null && node.children.map(_node => this.parseChildren(_node))
      };
    },

    // 渲染节点
    renderTreeContent(h, { data }) {
      let title = (<div class="tree-node-title" onClick={(e) => this.editData(e,data)}>{data.title}</div>);

      let addBtn = this.$store.state.perms.includes("sys:menu:save") ? (
          <span class="opt" onClick={(e) => this.addData(e,data)}>
              <i class="ivu-icon ivu-icon-md-add" />
            </span>
      ) : "";

      return (
          <div
              class={this.activeNode !== null && data.menuId === this.activeNode.menuId ? "tree-node active" : "tree-node"}
              onClick={(e) => this.editData(e,data)}
          >
            {title}
            <div class="tree-options">

              {(<span class="opt" onClick={(e) => this.editData(e,data)}>
              <i class="ivu-icon ivu-icon-md-create" />
            </span>)}
              {addBtn}
              {this.$store.state.perms.includes("sys:menu:delete") ? (<span class="opt" onClick={(e) => this.deleteData(e, data)}>
                <i class="ivu-icon ivu-icon-md-trash"/>
              </span>):""}
            </div>
          </div>
      );
    },
  }
};
</script>

<style scoped lang="less">
.contentBox{
  flex-direction: row;
  > .left{
    display: flex;
    max-width: 460px;
    flex: 1;
    padding: 20px;
    flex-direction: column;
    > .dept_content{
      display: flex;
      flex-direction: column;
      flex: 1;
      overflow: hidden;
      > .header{
        height: 44px;
        border-radius: 6px 6px 0 0;
        background: #4a9bff;
        color: white;
        text-align: center;
        line-height: 44px;
        cursor: pointer;
        font-size: 16px;
      }
      > .tree{
        display: flex;
        flex: 1;
        flex-direction: column;
        background: #f5f6f6;
        border: 1px solid #e1e3eb;
        border-radius: 0 0 6px 6px;
        overflow-y: scroll;
        border-top: none;
        padding: 10px 20px;
      }
      > .tree-radius{
        border: 1px solid #e1e3eb;
        border-radius: 6px;
      }
    }
  }
  > .right{
    display: flex;
    flex: 1;
    padding: 20px 20px 20px 0;
    flex-direction: column;
    overflow-y: scroll;
    > .header{
      display: flex;
      height: 44px;
      align-items: center;
      border-bottom: 1px solid #e8eaec;
      margin-bottom: 20px;
      > .line{
        width: 6px;
        height: 16px;
        margin-right: 8px;
        background: #285EE2;
        border-radius: 3px;
      }
      > .title{
        color: #333333;
        font-size: 16px;
      }
    }
  }



  // 树样式
  /deep/ .ivu-tree-empty{
    text-align: center;
  }
  /deep/ .tree-node {
    font-size: 14px;
    display: inline-block;
    vertical-align: top;
    &:hover {
      .tree-options {
        opacity: 1;
        transform: translateX(10px);
      }
    }
    &.active {
      .tree-node-title {
        color: #2d8cf0;
      }
      .tree-options {
        opacity: 1;
        transform: translateX(10px);
      }
    }
  }

  /deep/ .ivu-tree-arrow i{
    font-size: 16px;
    margin-top: -3px;
  }
  /deep/ .tree-ico {
    width: 14px;
    height: 14px;
    margin-right: 3px;
  }

  /deep/ .tree-node-title {
    margin-right: 10px;
    display: inline-block;
    cursor: pointer; // height: 18px;
    white-space: nowrap; // overflow: hidden;
    // text-overflow: ellipsis;
    &:hover {
      color: #337AF4;
    }
  }

  /deep/ .tree-options {
    display: inline-block;
    margin-right: 5px;
    opacity: 0;
    transform: translateX(-20px);
    transition: all .3s;
    >.opt {
      display: inline-block;
      width: 20px;
      height: 20px;
      margin-right: 5px;
      color: #FFF ;
      border: 1px solid #337AF4;
      background-color: #337AF4;
      border-radius: 4px;
      text-align: center;
      cursor: pointer;
      transition: all .5s;
      font-size: 12px;
      &:hover {
        border-color: #2d8cf0;
      }
    }
  }
  /deep/ .ivu-tree-title {
    font-size: 14px;
  }
}
</style>